feat(namespacesync): add NamespaceSyncController for per-namespace resource management - #3581
feat(namespacesync): add NamespaceSyncController for per-namespace resource management#3581jkhelil wants to merge 7 commits into
Conversation
c1be9cb to
c2fc182
Compare
c2fc182 to
481eaa9
Compare
a66cbfa to
ba1e9f7
Compare
|
@jkhelil - If you are still planning to pursue this PR, please rebase. |
|
@waveywaves @pratap0007 Would you mind review this please ? |
|
/assign @waveywaves |
…source management Add a new watch-based NamespaceSyncController that replaces the scan-based per-namespace reconciliation loop in rbac.go. The new controller uses Kubernetes informers to react to namespace, ServiceAccount, Secret, and TektonConfig events, eliminating O(N) API server calls on every TektonConfig reconcile. New typed API in TektonConfig.spec.platforms.openShift.namespaceSync: - createPipelineSA: manage the pipeline ServiceAccount (replaces createRbacResource) - createCABundles: manage CA bundle ConfigMaps (replaces createCABundleConfigMaps) - createEditRoleBinding: manage openshift-pipelines-edit RoleBinding (replaces legacyPipelineRbac) - createSCCRoleBinding: manage pipelines-scc-rolebinding (defaults true) - secretBindings: bind registry secrets (by name or label selector) to the pipeline SA Key behaviors: - Pipeline SA self-heals on add/update/delete events - Named secret bindings are removed from the pipeline SA when the secret is deleted - Label-based bindings re-evaluate on every secret add/delete event - TektonConfig updates only trigger a full namespace sweep when the NamespaceSync config itself changes (reflect.DeepEqual guard prevents thundering herd) - Legacy spec.params entries are migrated to the typed fields on first reconcile Design doc: docs/plans/2026-06-26-namespace-sync-controller-design.md Signed-off-by: Abdeljaouad Khelil <akhelil@redhat.com> Assisted-by: Claude Sonnet 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
When TektonConfig.spec.platforms.openShift.namespaceSync is configured (which is now the default), the NamespaceSyncController owns all per-namespace resources (pipeline SA, CA bundles, SCC RoleBinding, edit RoleBinding, secret bindings). The legacy rbac.go createResources loop now skips per-namespace iteration and only maintains cluster-scoped resources: - ensurePreRequisites: RBACInstallerSet, pipelines-scc-clusterrole, SCC validation - removeAndUpdateNSFromCI: ClusterInterceptors ClusterRoleBinding cleanup - handleClusterRoleBinding: keep openshift-pipelines-clusterinterceptors in sync using existing pipeline SAs collected via the new collectExistingPipelineSAs helper This commit can be reverted independently to restore the legacy scan-based per-namespace reconciliation without losing the NamespaceSyncController changes. Signed-off-by: Abdeljaouad Khelil <akhelil@redhat.com> Assisted-by: Claude Sonnet 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
…RoleBinding The openshift-pipelines-clusterinterceptors ClusterRoleBinding grants the pipeline SA in every user namespace get/list/watch access to ClusterInterceptors, which EventListeners need to resolve webhook interceptors. The previous implementation in rbac.go rebuilt the full subject list on every TektonConfig reconcile (O(N) API calls). NamespaceSyncController now manages this ClusterRoleBinding with a per-namespace patch: - Pipeline SA created / namespace reconciled → subject is added (idempotent). - Pipeline SA deleted → reconcile of that namespace removes the subject. - RetryOnConflict handles concurrent updates from parallel namespace workers. - ClusterRole is bootstrapped once; it never changes so no update path needed. Five new tests cover: creation, no-op when SA absent, idempotency, multi-namespace accumulation, and subject removal on SA deletion. Signed-off-by: Abdeljaoued Khelil <abdeljaouedkhelil@example.com> Assisted-by: Claude Sonnet 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
Now that NamespaceSyncController handles the openshift-pipelines-clusterinterceptors ClusterRoleBinding incrementally per namespace, rbac.go no longer needs to: - Accumulate all pipeline SAs via collectExistingPipelineSAs - Rebuild the full subject list via handleClusterRoleBinding The NamespaceSync guard in createResources is simplified: it now only calls ensurePreRequisites (cluster-scoped SCC ClusterRole + validation) before returning; all other RBAC and secret binding work is owned by the new controller. Signed-off-by: Abdeljaoued Khelil <abdeljaouedkhelil@example.com> Assisted-by: Claude Sonnet 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
…ped work Now that NamespaceSyncController owns all per-namespace resources (pipeline SA, CA bundles, SCC RoleBinding, edit RoleBinding, secret bindings, ClusterInterceptors subjects) and NamespaceSync is always defaulted to non-nil, the legacy per-namespace branch of rbac.go is permanently unreachable. Removed (~1 350 lines): - shouldIgnoreNamespace, needsRBAC, needsCABundle, getNamespacesToBeReconciled - processRBAC, handleSCCInNamespace, getSCCRoleInNamespace, patchNamespaceLabel - ensureSA, createSA, ensureSCCRoleInNamespace - ensurePipelinesSCCRoleBinding, createSCCRoleBinding, updateRoleBinding - ensureCABundles, ensureCABundlesInNamespace, createCABundleConfigMaps - createServiceCABundleConfigMap, patchNamespaceTrustedConfigLabel - ensureRoleBindings, createRoleBinding, isLegacyRBACEnabled - handleClusterRoleBinding, bulkUpdateClusterRoleBinding, bulkCreateClusterRoleBinding - createClusterRole, removeAndUpdateNSFromCI, removeIndex - updateOwnerRefs, removeAndUpdate, hasSubject, CompareSubjects, mergeSubjects - hasOwnerRefernce, cleanUpRBACNameChange (TODO: remove after v0.55.0 - now done) - NamespaceServiceAccount, NamespacesToReconcile types Kept: - createResources → only calls ensurePreRequisites (cluster-scoped) - ensurePreRequisites: InstallerSet, SCC validation, pipelines-scc-clusterrole - ensurePipelinesSCClusterRole: dynamic ClusterRole for default SCC - EnsureRBACInstallerSet, cleanUp, setDefault, removeObsoleteRBACInstallerSet extension.go: removed rbacInformer field (no longer needed), removed cleanUpRBACNameChange call, removed unused rbacV1 and rbacInformer imports. rbac_test.go: replaced 500-line dead-path test with focused tests for createResources (prerequisites path) and setDefault. Signed-off-by: Abdeljaoued Khelil <abdeljaouedkhelil@example.com> Assisted-by: Claude Sonnet 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
Add the namespacesync controller to the lifecycle container's -controllers arg so it actually runs on OpenShift. Add the namespaceSync field schema to the TektonConfig CRD so the API server accepts it. Embed reconciler.LeaderAwareFuncs in the Reconciler struct to satisfy Knative sharedmain's leader-election requirement. Signed-off-by: Jawed khelil <jkhelil@redhat.com> Assisted-by: Claude Sonnet 4.6 (via Cursor) Co-authored-by: Cursor <cursoragent@cursor.com>
The e2e test referenced tconfig.PipelineRoleBinding from the tektonconfig package, which no longer exists after the rbac.go cleanup. Export the constant from namespacesync (its new owner) and update the test import alias accordingly. Signed-off-by: Jawed khelil <jkhelil@redhat.com> Assisted-by: Claude Sonnet 4.6 (via Cursor) Co-authored-by: Cursor <cursoragent@cursor.com>
ba1e9f7 to
903059b
Compare
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3581 +/- ##
==========================================
+ Coverage 26.14% 26.20% +0.06%
==========================================
Files 465 467 +2
Lines 24940 24805 -135
==========================================
- Hits 6520 6500 -20
+ Misses 17698 17606 -92
+ Partials 722 699 -23
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Changes
Introduces a new
NamespaceSyncControllerthat replaces thescan-based batch processing in
rbac.gowith an event-driven,per-namespace reconciler. Addresses RFE-7814 (flexible service
account binding for Quay Robot credentials).
What this does
NamespaceSyncController— a watch-based controller thatreacts to Namespace, ServiceAccount, Secret, and TektonConfig
events to ensure per-namespace Tekton resources are present and
up to date in every user namespace
pipelineSA, SCC RoleBinding, edit RoleBinding, andCA bundle ConfigMaps in each namespace
openshift-pipelines-clusterinterceptorsCRBincrementally (add/remove only the affected namespace's subject)
spec.platforms.openshift .namespaceSync.secretBindings(the core RFE-7814 use case)spec.platforms.openshift.namespaceSyncAPI field toTektonConfig, replacing legacy
spec.paramsentriesrbac.goLeaderAwareFuncsembedding (required by Knative sharedmain)namespaceSyncschema to the TektonConfig CRDStatus
Work in progress — more e2e tests needed before merge:
make test lintfull passVerified on cluster
All per-namespace resources (pipeline SA, SCC RoleBinding, edit
RoleBinding, CA bundles, CRB subject) created correctly in new
namespaces within seconds. Established namespaces unaffected.
Submitter Checklist
make test lintbefore submitting a PRRelease Notes
Made with Cursor